home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_11 / plauger / complex.cpp < prev   
C/C++ Source or Header  |  1995-09-11  |  19KB  |  610 lines

  1. // complex standard header
  2. #ifndef _COMPLEX_
  3. #define _COMPLEX_
  4. #include <cmath>
  5. #include <istream>
  6. _STD_BEGIN
  7. #define __STD_COMPLEX
  8.         // TEMPLATE CLASS _Ctr
  9. template<class _T> class _Ctr {
  10. public:
  11.     static _T _Cosh(_T _X, _T _Y)
  12.         {return (::_Cosh((double)_X, (double)_Y)); }
  13.     static short _Exp(_T *_P, _T _Y, short _E)
  14.         {double _W = (double)*_P;
  15.         short _Ans = ::_Exp(&_W, (double)_Y, _E);
  16.         *_P = (_T)_W;
  17.         return (_Ans); }
  18.     static _T _Infv(_T)
  19.         {return (_Inf._D); }
  20.     static bool _Isinf(_T _X)
  21.         {double _W = (double)_X;
  22.         return (_Dtest(&_W) == _INF); }
  23.     static bool _Isnan(_T _X)
  24.         {double _W = (double)_X;
  25.         return (_Dtest(&_W) == _NAN); }
  26.     static _T _Nanv(_T)
  27.         {return (_Nan._D); }
  28.     static _T _Sinh(_T _X, _T _Y)
  29.         {return (::_Sinh((double)_X, (double)_Y)); }
  30.     static _T atan2(_T _Y, _T _X)
  31.         {return (::atan2((double)_Y, (double)_X)); }
  32.     static _T cos(_T _X)
  33.         {return (::cos((double)_X)); }
  34.     static _T exp(_T _X)
  35.         {return (::exp((double)_X)); }
  36.     static _T ldexp(_T _R, int _E)
  37.         {return (::ldexp((double)_R, _E)); }
  38.     static _T log(_T _X)
  39.         {return (::log((double)_X)); }
  40.     static _T pow(_T _X, _T _Y)
  41.         {return (::pow((double)_X, (double)_Y)); }
  42.     static _T sin(_T _X)
  43.         {return (::sin((double)_X)); }
  44.     static _T sqrt(_T _X)
  45.         {return (::sqrt((double)_X)); }
  46.     };
  47.         // CLASS _Ctr<float>
  48. class _Ctr<float> {
  49. public:
  50.     typedef float _T;
  51.     static _T _Cosh(_T _X, _T _Y)
  52.         {return (_FCosh(_X, _Y)); }
  53.     static short _Exp(_T *_P, _T _Y, short _E)
  54.         {return (_FExp(_P, _Y, _E)); }
  55.     static _T _Infv(_T)
  56.         {return (_FInf._F); }
  57.     static bool _Isinf(_T _X)
  58.         {return (_FDtest(&_X) == _INF); }
  59.     static bool _Isnan(_T _X)
  60.         {return (_FDtest(&_X) == _NAN); }
  61.     static _T _Nanv(_T)
  62.         {return (_FNan._F); }
  63.     static _T _Sinh(_T _X, _T _Y)
  64.         {return (_FSinh(_X, _Y)); }
  65.     static _T atan2(_T _Y, _T _X)
  66.         {return (atan2f(_Y, _X)); }
  67.     static _T cos(_T _X)
  68.         {return (cosf(_X)); }
  69.     static _T exp(_T _X)
  70.         {return (expf(_X)); }
  71.     static _T ldexp(_T _R, int _E)
  72.         {return (ldexpf(_R, _E)); }
  73.     static _T log(_T _X)
  74.         {return (logf(_X)); }
  75.     static _T pow(_T _X, _T _Y)
  76.         {return (powf(_X, _Y)); }
  77.     static _T sin(_T _X)
  78.         {return (sinf(_X)); }
  79.     static _T sqrt(_T _X)
  80.         {return (sqrtf(_X)); }
  81.     };
  82.         // CLASS _Ctr<double>
  83. class _Ctr<double> {
  84. public:
  85.     typedef double _T;
  86.     static _T _Cosh(_T _X, _T _Y)
  87.         {return (::_Cosh(_X, _Y)); }
  88.     static short _Exp(_T *_P, _T _Y, short _E)
  89.         {return (::_Exp(_P, _Y, _E)); }
  90.     static _T _Infv(_T)
  91.         {return (_Inf._D); }
  92.     static bool _Isinf(_T _X)
  93.         {return (_Dtest(&_X) == _INF); }
  94.     static bool _Isnan(_T _X)
  95.         {return (_Dtest(&_X) == _NAN); }
  96.     static _T _Nanv(_T)
  97.         {return (_Nan._D); }
  98.     static _T _Sinh(_T _X, _T _Y)
  99.         {return (::_Sinh(_X, _Y)); }
  100.     static _T atan2(_T _Y, _T _X)
  101.         {return (::atan2(_Y, _X)); }
  102.     static _T cos(_T _X)
  103.         {return (::cos(_X)); }
  104.     static _T exp(_T _X)
  105.         {return (::exp(_X)); }
  106.     static _T ldexp(_T _R, int _E)
  107.         {return (::ldexp(_R, _E)); }
  108.     static _T log(_T _X)
  109.         {return (::log(_X)); }
  110.     static _T pow(_T _X, _T _Y)
  111.         {return (::pow(_X, _Y)); }
  112.     static _T sin(_T _X)
  113.         {return (::sin(_X)); }
  114.     static _T sqrt(_T _X)
  115.         {return (::sqrt(_X)); }
  116.     };
  117.         // CLASS _Ctr<long double>
  118. class _Ctr<long double> {
  119. public:
  120.     typedef long double _T;
  121.     static _T _Cosh(_T _X, _T _Y)
  122.         {return (_LCosh(_X, _Y)); }
  123.     static short _Exp(_T *_P, _T _Y, short _E)
  124.         {return (_LExp(_P, _Y, _E)); }
  125.     static _T _Infv(_T)
  126.         {return (_LInf._L); }
  127.     static bool _Isinf(_T _X)
  128.         {return (_LDtest(&_X) == _INF); }
  129.     static bool _Isnan(_T _X)
  130.         {return (_LDtest(&_X) == _NAN); }
  131.     static _T _Nanv(_T)
  132.         {return (_LNan._L); }
  133.     static _T _Sinh(_T _X, _T _Y)
  134.         {return (_LSinh(_X, _Y)); }
  135.     static _T atan2(_T _Y, _T _X)
  136.         {return (atan2l(_Y, _X)); }
  137.     static _T cos(_T _X)
  138.         {return (cosl(_X)); }
  139.     static _T exp(_T _X)
  140.         {return (expl(_X)); }
  141.     static _T ldexp(_T _R, int _E)
  142.         {return (ldexpl(_R, _E)); }
  143.     static _T log(_T _X)
  144.         {return (logl(_X)); }
  145.     static _T pow(_T _X, _T _Y)
  146.         {return (powl(_X, _Y)); }
  147.     static _T sin(_T _X)
  148.         {return (sinl(_X)); }
  149.     static _T sqrt(_T _X)
  150.         {return (sqrtl(_X)); }
  151.     };
  152.         // TEMPLATE CLASS _Complex_base
  153. template<class _T> class complex;
  154. class complex<float>;
  155. class complex<double>;
  156. class complex<long double>;
  157. template<class _T>
  158.     class _Complex_base {
  159. public:
  160.     typedef _Complex_base<_T> _Myt;
  161.     _Complex_base(const _T& _R, const _T& _I)
  162.         : _Re(_R), _Im(_I) {}
  163. #if _HAS_MEMBER_TEMPLATES
  164.     template class<U>
  165.         _Myt& operator=(const complex<_U>& _X)
  166.         {_Re = (_T)_X.real();
  167.         _Im = (_T)_X.imag();
  168.         return (*this); }
  169.     template<class _U>
  170.         _Myt& operator+=(const complex<_U>& _X)
  171.         {_Re += (_T)_X.real();
  172.         _Im += (_T)_X.imag();
  173.         return (*this); }
  174.     template<class _U>
  175.         _Myt& operator-=(const complex<_U>& _X)
  176.         {_Re -= (_T)_X.real();
  177.         _Im -= (_T)_X.imag();
  178.         return (*this); }
  179.     template<class _U>
  180.         _Myt& operator*=(const complex<_U>& _X)
  181.         {_T _Xre = (_T)_X.real();
  182.         _T _Xim = (_T)_X.imag();
  183.         _T _W = _Re * _Xre - _Im * _Xim;
  184.         _Im = _Re * _Xim + _Im * _Xre;
  185.         _Re = _W;
  186.         return (*this); }
  187.     template class<U>
  188.         _Myt& operator/=(const complex<_U>& _X)
  189.         {_T _Xre = (_T)_X.real();
  190.         _T _Xim = (_T)_X.imag();
  191.         if (_Ctr<_T>::_Isnan(_Xre) || _Ctr<_T>::_Isnan(_Xim))
  192.             _Re = _Ctr<_T>::_Nanv(_Xre), _Im = _Re;
  193.         else if ((_Xim < 0 ? -_Xim : +_Xim)
  194.             < (_Xre < 0 ? -_Xre : +_Xre))
  195.             {_T _Wr = _Xim / _Xre;
  196.             _T _Wd = _Xre + _Wr * _Xim;
  197.             if (_Ctr<_T>::_Isnan(_Wd) || _Wd == 0)
  198.                 _Re = _Ctr<_T>::_Nanv(_Xre), _Im = _Re;
  199.             else
  200.                 {_T _W = (_Re + _Im * _Wr) / _Wd;
  201.                 _Im = (_Im - _Re * _Wr) / _Wd;
  202.                 _Re = _W; }}
  203.         else if (_Xim == 0)
  204.             _Re = _Ctr<_T>::_Nanv(_Xre), _Im = _Re;
  205.         else
  206.             {_T _Wr = _Xre / _Xim;
  207.             _T _Wd = _Xim + _Wr * _Xre;
  208.             if (_Ctr<_T>::_Isnan(_Wd) || _Wd == 0)
  209.                 _Re = _Ctr<_T>::_Nanv(_Xre), _Im = _Re;
  210.             else
  211.                 {_T _W = (_Re * _Wr + _Im) / _Wd;
  212.                 _Im = (_Im * _Wr - _Re) / _Wd;
  213.                 _Re = _W; }}
  214.         return (*this); }
  215. #else
  216.     _T real(_T _X)
  217.         {return (_Re = _X); }
  218.     _T imag(_T _X)
  219.         {return (_Im = _X); }
  220. #endif
  221.     _T real() const
  222.         {return (_Re); }
  223.     _T imag() const
  224.         {return (_Im); }
  225. private:
  226.     _T _Re, _Im;
  227.     };
  228.         // CLASS complex<float>
  229. class complex<float> : public _Complex_base<float> {
  230. public:
  231.     typedef float _T;
  232.     explicit complex(const complex<double>&);
  233.     explicit complex(const complex<long double>&);
  234.     complex(const _T& _R = 0, const _T& _I = 0)
  235.         : _Complex_base<_T>(_R, _I) {}
  236.     };
  237.         // CLASS complex<double>
  238. class complex<double> : public _Complex_base<double> {
  239. public:
  240.     typedef double _T;
  241.     complex(const complex<float>&);
  242.     explicit complex(const complex<long double>&);
  243.     complex(const _T& _R = 0, const _T& _I = 0)
  244.         : _Complex_base<_T>(_R, _I) {}
  245.     };
  246.         // CLASS complex<long double>
  247. class complex<long double> : public _Complex_base<long double> {
  248. public:
  249.     typedef long double _T;
  250.     complex(const complex<float>&);
  251.     complex(const complex<double>&);
  252.     complex(const _T& _R = 0, const _T& _I = 0)
  253.         : _Complex_base<_T>(_R, _I) {}
  254.     };
  255.         // CONSTRUCTORS FOR complex SPECIALIZATIONS
  256. complex<float>::complex(const complex<double>& _X)
  257.     : _Complex_base<float>((_T)_X.real(), (_T)_X.imag()) {}
  258. complex<float>::complex(const complex<long double>& _X)
  259.     : _Complex_base<float>((_T)_X.real(), (_T)_X.imag()) {}
  260. complex<double>::complex(const complex<float>& _X)
  261.     : _Complex_base<double>((_T)_X.real(), (_T)_X.imag()) {}
  262. complex<double>::complex(const complex<long double>& _X)
  263.     : _Complex_base<double>((_T)_X.real(), (_T)_X.imag()) {}
  264. complex<long double>::complex(const complex<float>& _X)
  265.     : _Complex_base<long double>((_T)_X.real(), (_T)_X.imag()) {}
  266. complex<long double>::complex(const complex<double>& _X)
  267.     : _Complex_base<long double>((_T)_X.real(), (_T)_X.imag()) {}
  268.         // TEMPLATE CLASS complex
  269. template<class _T>
  270.     class complex : public _Complex_base<_T> {
  271. public:
  272.     complex(const _T& _R = 0, const _T& _I = 0)
  273.         : _Complex_base<_T>(_R, _I) {}
  274. #if _HAS_MEMBER_TEMPLATES
  275.     template<class _U>
  276. #else
  277.     typedef _T _U;
  278. #endif
  279.         complex(const complex<_U>& _X)
  280.         : _Complex_base<_T>((_T)_X.real(), (_T)_X.imag()) {}
  281.     };
  282. #if !_HAS_MEMBER_TEMPLATES
  283.         // TEMPLATE complex OPERATORS
  284. template<class _T, class _U> inline
  285.     complex<_T>& operator=(complex<_T>& _X, const complex<_U>& _Y)
  286.     {_X.real((_T)_X.real());
  287.     _X.imag((_T)_X.imag());
  288.     return (_X); }
  289. template<class _T, class _U> complex<_T>& operator+=(
  290.     complex<_T>& _X,
  291.     const comp